package c.c.k.controller;

import c.c.k.config.StockConfig;
import c.c.k.emums.EnumSuggestionType;
import c.c.k.pojo.*;
import c.c.k.repository.StockRepository;
import c.c.k.service.*;
import c.c.k.util.BeanUtil;
import c.c.k.util.StockContants;
import c.c.k.vo.FundVO;
import c.c.k.vo.PercentVO;
import c.c.k.vo.StockVO;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.RandomUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * Created by chenck on 2022/3/19.
 */
@Controller
public class HtmlController {
    @Autowired
    private StockService stockService;
    @Autowired
    private StockRepository stockRepository;
    @Autowired
    private FundService fundService;
    @Autowired
    private FundStockService fundStockService;
    @Autowired
    private UserStockService userStockService;
    @Autowired
    private EventService eventService;

    @GetMapping("/")
    public Object home(Model model){
        List<Long> ids = userStockService.listByUserId(StockContants.DEF_USER_ID).stream().map(UserStock::getStockId).collect(Collectors.toList());
        List<Stock> stocks = stockService.listStock(ids);
        stocks.sort((a,b)->new Double((a.getNowPrice()/a.getMaxPrice()-b.getNowPrice()/b.getMaxPrice()) * 100).intValue());
        this.setStocks(stocks, model);
        return "home";
    }

    @GetMapping("/event")
    public Object event(Model model){
        List<Long> stockIds = userStockService.listByUserId(StockContants.DEF_USER_ID).stream().map(UserStock::getStockId).collect(Collectors.toList());
        PageRequest pageRequest = PageRequest.of(0, 10, Sort.Direction.DESC, "date");
        List<Event> events = eventService.listEvent(stockIds, pageRequest);
        model.addAttribute("events", events);
        return "event";
    }

    @GetMapping("/stock")
    public Object stock(
            @RequestParam(name = "minShizhi",defaultValue = "500") Integer minShizhi,
            @RequestParam(name = "maxShizhi",defaultValue = "100000") Integer maxShizhi,
            @RequestParam(name = "jys",defaultValue = "sh") String jys,
            Model model){
        List<Stock> stocks = stockService.listStockByPercent(minShizhi, maxShizhi, jys);
        this.setStocks(stocks, model);
        model.addAttribute("minShizhi", minShizhi);
        model.addAttribute("maxShizhi", maxShizhi);
        model.addAttribute("jys", jys);
        return "stock";
    }

    private void setStocks(List<Stock> stocks, Model model){
        List<StockVO> stockVOS = BeanUtil.batchTransform(StockVO.class, stocks);
        List<Long> stockIds = userStockService.listByUserId(StockContants.DEF_USER_ID).stream().map(UserStock::getStockId).collect(Collectors.toList());
        int index = 1;
        for (StockVO stockVO : stockVOS) {
            stockVO.setIndex(index++);
            stockVO.setHasFollow(stockIds.contains(stockVO.getId()));
        }
        model.addAttribute("stocks", stockVOS);
    }

    @GetMapping("/fundByStock")
    public Object fundByStock(
            Long stockId,
            Model model){
        List<Long> collect = fundStockService.listByStockId(stockId, 8D).stream().map(FundStock::getFundId).collect(Collectors.toList());
        List<Fund> funds = fundService.listFund(collect);
        Stock stock = stockRepository.getOne(stockId);
        return this.fundPage(funds, "持仓" + stock.getName() + "占比大于8%的相关基金", stockId, model);
    }

    @GetMapping("/fund")
    public Object fund(Model model){
        List<Fund> funds = fundService.listFund();
        return this.fundPage(funds,"基金列表", 0L, model);
    }

    private Object fundPage(List<Fund> funds, String title, Long stockId, Model model){
        List<FundVO> fundVOS = BeanUtil.batchTransform(FundVO.class, funds);
        for (FundVO fundVO : fundVOS) {
            List<FundStock> fundStocks = fundStockService.listByFundId(fundVO.getId());

            Map<Long, FundStock> map = MapUtil.newHashMap();
            fundStocks.forEach(f->{map.put(f.getStockId(), f);});

            List<Stock> stockList = stockRepository.findAllById(map.keySet());
            List<StockVO> stockVOS = BeanUtil.batchTransform(StockVO.class, stockList);
            stockVOS.forEach(stockVO -> {stockVO.setPercent(map.get(stockVO.getId()).getPercent());});
            stockVOS.sort(Comparator.comparing(StockVO::getPercent).reversed());
            double avg = stockList.stream().mapToDouble(stock -> stock.getNowPrice() / stock.getMaxPrice()).sum()/stockList.size();
            fundVO.setAvgLoss(avg);

            fundVO.setList(stockVOS);
            fundVO.setSuggestionType(stockVOS.get(0).getSuggestionType());
        }
        fundVOS.sort(Comparator.comparing(FundVO::getType).reversed());
        int index = 1;
        for (FundVO fundVO : fundVOS) {
            fundVO.setIndex(index++);
        }
        model.addAttribute("funds", fundVOS);
        model.addAttribute("suggestionTypes", EnumSuggestionType.values());
        model.addAttribute("title", title);
        model.addAttribute("stockId", stockId);
        return "fund";
    }

    @GetMapping("/left")
    public Object left(
            Model model){
        double start = 0.4;
        int startUnit = 0;
        List<PercentVO> percents = Arrays
                .asList(0.4, 0.3, 0.2, 0.1)
                .stream().map(f->PercentVO.builder().percent(f).build())
                .collect(Collectors.toList());

        double cost = 0;
        int totalUnit = 0;
        for (int i = 0; i < percents.size(); i++) {
            PercentVO percentVO = percents.get(i);
            if(percentVO.getPercent() <= start){
                //int d = new Double(Math.pow(2, startUnit)).intValue();
                ++startUnit;
                percentVO.setUnit(startUnit);
            }else {
                percentVO.setUnit(0);
            }
            cost += percentVO.getUnit()*percentVO.getPercent();
            totalUnit += percentVO.getUnit();
            percentVO.setLoss(cost == 0 ? 0 : (1 - totalUnit*percentVO.getPercent()/cost) * 100);
            percentVO.setTotalUnit(totalUnit);
            percentVO.setAvg(totalUnit == 0 ? 0 : cost/totalUnit);
        }

        model.addAttribute("percents", percents);
        return "left";
    }

}
